import java.net.*;
import java.io.*;


/** Class thread communication with one client. */
public class ServerConnection extends Thread {

    /** client's socket.*/
    private Socket socket;
    /** data buffer received from socket.*/
    private BufferedReader in;
    /**data buffer sending to socket.*/
    private PrintWriter out;
    /**data received from client.*/
    private String dataIn;
    /**date sends from client.*/
    private String dataOut;
    /** Server's Manager of Clients.*/
    private ManagerOfClients moc;
    /** Client's object */
    private Player client;
    /** If it's true, Thread ends listen the client. */
    private boolean end;
    
    private boolean startGame;

     /**constructor.
     * @param socket client's socket.
     * @param moc ManagerOfClients
     * @param Client client
     * @throws ServerException, when client's socket throws IOException.
     */
    public ServerConnection(final Socket socket, final ManagerOfClients moc, final Player client) throws ServerException
     {
        this.socket = socket;
        this.client = client;
		this.moc = moc;
		this.dataIn = " ";
		this.dataOut = " ";
		this.startGame = false; 
		this.end = false;
		try
		{
			this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			this.out = new PrintWriter(socket.getOutputStream(), true);
		}
		catch(IOException e)
		{
			throw new ServerException("Input/output Exception");
		}
		System.out.println(this.client.getNumber()+"is conected");
		
	}
    /**constor for tmp connection 
     * @param socket client's socket.
     * @param moc ManagerOfClients
     * @throws ServerException, when client's socket throws IOException.
     */
    public ServerConnection(final Socket socket, final ManagerOfClients moc)
    {
       this.socket = socket;
		this.moc = moc;
		this.dataIn = " ";
		this.dataOut = " ";

		try
		{
			this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			this.out = new PrintWriter(socket.getOutputStream(), true);
		}
		catch(IOException e)
		{
			System.err.println("Input/Output error");
		}
		this.start();
	}
	/**method which executes query from client*/
	private void execute()
	{
		if (dataIn.startsWith("Chat_")){

            moc.sendToAllClients("Chat_"+this.client.getNick()+":"+dataIn.substring(5));
			}
		if(dataIn.startsWith("RejctPlayer_"))
		{System.out.println(dataIn);
			int i =-1;
			if(!startGame)
			{
			try{
				
			i = Integer.parseInt(dataIn.substring(12));
			}
			catch(NumberFormatException e)
			{
				dataOut = "Error_invalid_playr_id";
			}
				moc.rejectPlayer(i,client.getNumber());
			}
			else
				send("Wait_");
		}
		if(startGame)
		{
			client.run(dataIn);
			
		}
		else{ 
		
			if(dataIn.startsWith("Name_"))
			{
					client.setNick(dataIn.substring(5));
					System.out.println("New Player's nick " + client.getNick());
					moc.refreshClientsList();
				
			}
			else if(dataIn.startsWith("StartGame_"))
				{
					System.out.println("StartGame");
					this.client.ready();
						moc.startGame(this.client.getNumber());
						

					
				}
		
			//vote:1 - reject, 0- not reject
			else if(dataIn.startsWith("reject_"))
			{
				
				int vote = 0;
				try{
					 vote = Integer.parseInt(dataIn.substring(7));
					 System.out.println("vote"+vote);
					}
					catch(NumberFormatException e)
					{
						dataOut = "Error_invalid_playr_id";
					}
				if(client.rightToVote)
				{
					moc.reject(vote);
					client.rightToVote=false;
				}
			}
				
			else if(dataIn.startsWith("AddBot_"))
			{
			
					moc.addBot();
			}
			if(dataIn.startsWith("ERROR_"))
			{
			    String Error =	dataIn.substring(6);
				System.err.println(dataIn.substring(6));
				if(Error == "Number")
				{
					send("Number_" + client.getNumber());
				}
				
			}

		}
			
		this.dataIn = " ";
			
		
	}
	public void end()
	{
		end = true;
	}
	/**Method allows send data to client from server
	 * @param data sends to client
	 * @param data, data sends to client */
	public void send( String data)
	{
		System.out.println("send"+data);
		this.out.println(data);
	}
	
	public void startGame()
	{
		startGame = true;
	}
	public void stopGame()
	{
		startGame = false;
	}
	public void endGame()
	{
		startGame = false;
	}
	/**method which executes the thread */
	public void run()
	{
		while(!end)
		{
			if(!this.socket.isConnected())
			{
				System.out.println("close");
				end = true;
				break;
			}
			try
			{
			//System.out.println(dataOut);
			//System.out.println("run");
			if(dataOut.equals(" ") )
			{
				try{
					dataIn = in.readLine();
					System.out.println("read");
                }
				catch(IOException e)
				{
					this.client.run("Fold_");
					out.println("You_are_disconect");
					end = true;
				}
				if(dataIn == null)
				{
					out.println("You_are_disconect");
					System.out.println("Player diconeted");
					end = true;
					break;
				}
				//System.out.println(dataIn);
				this.execute();
				
			}
			//System.out.println("run"+dataOut);
			if(!dataOut.equals(" "))
			{
				out.println(dataOut);
				dataOut = " ";
			}
            dataIn = " ";
			
				this.sleep(10);
			}
			 catch (InterruptedException e) {
				// TODO Auto-generated catch block
				System.out.println(e.getMessage());
			}
		}
		
		this.moc.deleteClient(this.client.getNumber());	
		this.interrupt();
	}

}




